/****************************************************************************
 *  _____       ______  _____
 * |_   _|     |  ____|/ ____|
 *   | |  _ __ | |__  | (___    Institute of Embedded Systems
 *   | | | '_ \|  __|  \___ \   Zürcher Hochschule für Angewandte
 *  _| |_| | | | |____ ____) |  Wissenschaften
 * |_____|_| |_|______|_____/   8401 Winterthur, Switzerland
 *
 ****************************************************************************
 *
 * @version $Rev: 153 $
 * @author  $Author: bacr $
 * @date    $Date: 2013-10-10 17:25:34 +0200 (jeu., 10 oct. 2013) $
 *
 ***************************************************************************/

#ifndef __PTP2_SLAVE_H__
#define __PTP2_SLAVE_H__

/* copy */
#ifndef __PTP_NODE_TABLE_DEFINES__
#define __PTP_NODE_TABLE_DEFINES__

typedef struct ptp2_lut_t                   ptp2_lut_t;
typedef struct ptp2_lut_entry_t             ptp2_lut_entry_t;

typedef struct ptp2_slave_t                 ptp2_slave_t;
typedef enum   ptp2_slave_step_t            ptp2_slave_step_t;

typedef struct ptp2_node_address_t          ptp2_node_address_t;

#endif

#include <stdint.h>
#include <stdbool.h>

#include "hcpp/ptp2_types.h"
#include "hcpp/ptp2_node_address.h"
#include "hcpp/ptp2_lut.h"

#include "packet/packet.h"

#define PTP2_SLAVE_LOG_PERIOD_DENIED        127

#define PTP2_SLAVE_SYNC_LOG_PERIOD_MIN      -7
#define PTP2_SLAVE_SYNC_LOG_PERIOD_MAX      4
#define PTP2_SLAVE_ANNOUNCE_LOG_PERIOD_MIN  -3
#define PTP2_SLAVE_ANNOUNCE_LOG_PERIOD_MAX  4


enum ptp2_slave_step_t {
    PTP2_SLAVE_ONE_STEP = 0,
    PTP2_SLAVE_TWO_STEP
};

/** Holds all information about a slave */
struct ptp2_slave_t {
    ptp2_lut_entry_t           *lut_entry;                              /**<  */
    ptp2_node_address_t        *address;                                /**<  */
    ptp2_port_identity_t        port_identity;                          /**< slave port identity used for signaling (can be filled with 0xFF if not known) */
    ptp2_slave_step_t           step;                                   /**< one step / two step */
    uint16_t                    seq_id;                                 /**< sequence counter used for signaling */
    int8_t                      sync_log_period;                        /**< granted logarithmic sync rate (-7...4 provided, 127 = not granted) */
    uint32_t                    sync_duration;                          /**< duration in seconds for message type 'sync' */
    uint64_t                    sync_expire;                            /**< expire time in seconds for message type 'sync' */
    int8_t                      announce_log_period;                    /**< granted logarithmic announce rate ( -3...4 provided, 127 = not granted) */
    uint32_t                    announce_duration;                      /**< duration in seconds for message type 'announce' */
    uint64_t                    announce_expire;                        /**< expire time in seconds for message type 'announce' */
    int8_t                      delay_response_log_period;              /**< granted logarithmic delay response rate (127 = not granted) */
    uint32_t                    delay_response_duration;                /**< duration in seconds for message type 'delay response' */
    uint64_t                    delay_response_expire;                  /**< expire time in seconds for message type 'delay response' */
    uint16_t                    position;                               /**< index in FPGA offload table */
};

void ptp2_slave_init(ptp2_slave_t *this, ptp2_lut_entry_t *lut_entry, ptp2_node_address_t *address, uint16_t position);

#endif

